package com.bailian.system.utils;

import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.bailian.system.domain.BlParkTags;
import com.bailian.system.domain.BlWarehouseType;
import com.bailian.system.domain.BlParkConfig;
import com.bailian.system.domain.BlParkService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * JSON工具类
 * 
 * @author bailian
 * @date 2025-08-04
 */
public class JsonUtils {
    
    private static final Logger log = LoggerFactory.getLogger(JsonUtils.class);
    private static final ObjectMapper objectMapper = new ObjectMapper();
    
    // 添加缓存机制，避免重复解析相同的JSON字符串
    private static final ConcurrentHashMap<String, Object> jsonCache = new ConcurrentHashMap<>();
    private static final int MAX_CACHE_SIZE = 1000;
    
    /**
     * 将JSON字符串转换为BlParkTags列表
     * 
     * @param json JSON字符串
     * @return BlParkTags列表
     */
    public static List<BlParkTags> parseParkTags(String json) {
        return parseJsonWithCache(json, "parkTags", new TypeReference<List<BlParkTags>>() {});
    }
    
    /**
     * 将BlParkTags列表转换为JSON字符串
     * 
     * @param parkTagsList BlParkTags列表
     * @return JSON字符串
     */
    public static String toParkTagsJson(List<BlParkTags> parkTagsList) {
        return toJsonString(parkTagsList, "parkTags");
    }
    
    /**
     * 将JSON字符串转换为BlWarehouseType列表
     * 
     * @param json JSON字符串
     * @return BlWarehouseType列表
     */
    public static List<BlWarehouseType> parseWarehouseTypes(String json) {
        return parseJsonWithCache(json, "warehouseTypes", new TypeReference<List<BlWarehouseType>>() {});
    }
    
    /**
     * 将BlWarehouseType列表转换为JSON字符串
     * 
     * @param warehouseTypesList BlWarehouseType列表
     * @return JSON字符串
     */
    public static String toWarehouseTypesJson(List<BlWarehouseType> warehouseTypesList) {
        return toJsonString(warehouseTypesList, "warehouseTypes");
    }    
    /**
     * 通用的JSON转换方法
     * 
     * @param obj 要转换的对象
     * @param type 类型标识
     * @return JSON字符串
     */
    private static String toJsonString(Object obj, String type) {
        if (obj == null) {
            return null;
        }
        try {
            return objectMapper.writeValueAsString(obj);
        } catch (Exception e) {
            log.error("转换对象为JSON失败 [{}]", type, e);
            return null;
        }
    }
    
    /**
     * 将JSON字符串转换为BlParkConfig列表
     * 
     * @param json JSON字符串
     * @return BlParkConfig列表
     */
    public static List<BlParkConfig> parseHardwareConfig(String json) {
        return parseJsonWithCache(json, "hardwareConfig", new TypeReference<List<BlParkConfig>>() {});
    }
    
    /**
     * 将BlParkConfig列表转换为JSON字符串
     * 
     * @param hardwareConfigList BlParkConfig列表
     * @return JSON字符串
     */
    public static String toHardwareConfigJson(List<BlParkConfig> hardwareConfigList) {
        return toJsonString(hardwareConfigList, "hardwareConfig");
    }
    
    /**
     * 将JSON字符串转换为BlParkService列表
     * 
     * @param json JSON字符串
     * @return BlParkService列表
     */
    public static List<BlParkService> parseParkServices(String json) {
        return parseJsonWithCache(json, "parkServices", new TypeReference<List<BlParkService>>() {});
    }
    
    /**
     * 将BlParkService列表转换为JSON字符串
     * 
     * @param parkServicesList BlParkService列表
     * @return JSON字符串
     */
    public static String toParkServicesJson(List<BlParkService> parkServicesList) {
        return toJsonString(parkServicesList, "parkServices");
    }
    
    /**
     * 将JSON字符串转换为仓库标签列表
     * 
     * @param json JSON字符串
     * @return BlParkTags列表
     */
    public static List<BlParkTags> parseWarehouseTags(String json) {
        return parseJsonWithCache(json, "warehouseTags", new TypeReference<List<BlParkTags>>() {});
    }
    
    /**
     * 将仓库标签列表转换为JSON字符串
     * 
     * @param warehouseTagsList 仓库标签列表
     * @return JSON字符串
     */
    public static String toWarehouseTagsJson(List<BlParkTags> warehouseTagsList) {
        return toJsonString(warehouseTagsList, "warehouseTags");
    }
    
    /**
     * 通用的JSON解析方法（带缓存）
     * 
     * @param json JSON字符串
     * @param cacheKey 缓存键
     * @param typeReference 类型引用
     * @return 解析后的对象
     */
    @SuppressWarnings("unchecked")
    private static <T> T parseJsonWithCache(String json, String cacheKey, TypeReference<T> typeReference) {
        if (json == null || json.trim().isEmpty()) {
            return null;
        }
        
        // 生成缓存键
        String cacheKeyFull = cacheKey + ":" + json.hashCode();
        
        // 尝试从缓存获取
        Object cached = jsonCache.get(cacheKeyFull);
        if (cached != null) {
            return (T) cached;
        }
        
        try {
            T result = objectMapper.readValue(json, typeReference);
            
            // 添加到缓存（限制缓存大小）
            if (jsonCache.size() >= MAX_CACHE_SIZE) {
                // 简单的LRU策略：清除一半缓存
                jsonCache.clear();
            }
            jsonCache.put(cacheKeyFull, result);
            
            return result;
        } catch (Exception e) {
            log.error("解析JSON失败 [{}]: {}", cacheKey, json, e);
            return null;
        }
    }
    
    /**
     * 检查JSON字符串是否包含指定名称（用于模糊查询）
     * 
     * @param json JSON字符串
     * @param name 要查找的名称
     * @return 是否包含
     */
    public static boolean containsName(String json, String name) {
        if (json == null || name == null || json.trim().isEmpty() || name.trim().isEmpty()) {
            return false;
        }
        
        try {
            // 简单的字符串匹配，避免完整解析JSON
            return json.toLowerCase().contains(name.toLowerCase());
        } catch (Exception e) {
            log.error("检查JSON名称失败: json={}, name={}", json, name, e);
            return false;
        }
    }
    
    /**
     * 清除缓存
     */
    public static void clearCache() {
        jsonCache.clear();
    }
    
    /**
     * 获取缓存大小
     * 
     * @return 缓存大小
     */
    public static int getCacheSize() {
        return jsonCache.size();
    }
} 